"""
Case Type   : 资源池化故障模式库
Case Name   : 配置参数设置错误-主备配置文件的参数配置错误
Create At   : 2025/04
Owner       : haomeng
Description :
    1、查看集群状态
    2、运行tpcc业务
    3、修改主节点配置文件中任意参数为异常值
    4、查看业务运行情况
    5、重启集群
    6、恢复原postgresql.conf配置文件
    7、拉起被踢出节点
    8、查看集群状态
Expect      :
    1、集群状态正常
    2、运行业务成功
    3、修改参数值成功
    4、业务运行正常无影响
    5、重启集群失败，原主节点被踢出
    6、恢复原postgresql.conf文件成功
    7、启动集群成功
    8、集群状态正常
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

class SSFauleMode(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.user_node = [Node(node='PrimaryRoot'), Node(node='PrimaryDbUser')]
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.com = Common()
        self.constant = Constant()
        self.conf_file = os.path.join(macro.DB_INSTANCE_PATH, macro.DB_PG_CONFIG_NAME)
        self.db_log = os.path.join(macro.DB_INSTANCE_PATH, 'DBstart.log')
        self.param = 'max_connections'

        self.log.info('----获取参数默认值----')
        self.default = self.com.show_param(self.param)
        self.log.info(f'----{self.param}默认值为{self.default}----')

    def test_ss_faule(self):
        text = '-----step1:查看集群状态;  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')

        text = '-----step2:执行tpcc读写业务  expect:业务执行成功-----'
        self.log.info(text)

        tpcc_cmd = f'./runBenchmark.sh {macro.PROPS_FILENAME}'
        self.log.info(tpcc_cmd)

        tpcc_execute = ComThread(self.com.start_tpcc, args=(self.user_node[0],
                                                            f'{macro.TPCC_PATH}',
                                                            tpcc_cmd))
        tpcc_execute.setDaemon(True)
        tpcc_execute.start()

        text = '-----step3:修改主节点配置文件中任意参数为异常值  expect:修改参数成功-----'
        self.log.info(text)

        delete = f"cp {self.conf_file} {self.conf_file}_bakkk; " \
                 f"sed -i 's/{self.param} = {self.default}/{self.param} = 123456789/g'  {self.conf_file};" \
                 f"cat {self.conf_file} | grep max_connections;"
        self.log.info(delete)

        delete_execute = ComThread(self.com.get_sh_result, args=(self.user_node[1], delete))
        delete_execute.setDaemon(True)
        delete_execute.start()

        text = '-----step4:查看业务运行情况  expect:业务运行正常无影响-----'
        self.log.info(text)

        tpcc_execute.join(10 * 60)
        ret1 = tpcc_execute.get_result()
        self.log.info(ret1)
        self.assertIn('Session End', ret1, 'tpcc执行失败')

        delete_execute.join(10 * 60)
        ret2 = delete_execute.get_result()
        self.log.info(ret2)
        self.assertIn('123456789', ret2, '修改参数失败')

        text = '-----step5:重启集群  expect:重启失败，对应日志中报错error-----'
        self.log.info(text)

        restart = self.pri_sh.exec_cm_ctl('stop;', 'cm_ctl start -t 30')
        self.log.info(restart)
        self.assertIn(self.constant.cm_stop_success_msg, restart, '重启集群失败')
        self.assertIn(self.constant.cm_start_failed_msg, restart, '启动集群成功')

        time.sleep(60)
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertNotIn('cluster_state  ：Normal', status, '集群状态正常')
        self.assertIn('S Primary', status, '集群状态异常')

        cat_log = f"cat {self.db_log} | grep '{self.param}'"
        self.log.info(cat_log)
        cat_execute = self.user_node[1].sh(cat_log).result()
        self.log.info(cat_execute)
        self.assertIn('outside the valid range', cat_execute, '日志中无异常')

    def tearDown(self):
        text = '-----step6:恢复原postgresql.conf文件  expect:恢复成功-----'
        self.log.info(text)

        mv = f'mv {self.conf_file}_bakkk {self.conf_file};' \
             f'cat {self.conf_file} | grep max_connections;'
        self.log.info(mv)
        mv_execute = self.user_node[1].sh(mv).result()
        self.log.info(mv_execute)

        text = '-----step7:拉起被踢出节点  expect:启动成功-----'
        self.log.info(text)

        start = self.pri_sh.exec_cm_ctl('start')
        self.log.info(start)

        text = '-----step8:查看集群状态  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        if 'P primary' not in status:
            switch = self.pri_sh.exec_cm_ctl('switchover', '-a')
            self.log.info(switch)
            self.assertIn(self.constant.SWITCHOVER_SUCCESS_MSG, switch, '切换成功')
        self.assertIn('Normal', status, '集群状态异常')
        self.assertIn(f'{self.default}', mv_execute, '恢复配置文件失败')
        self.log.info(f'----{os.path.basename(__file__)} end----')
